namespace WorkBasket
{
    using Auth0.AspNet;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IdentityModel.Services;
    using System.Linq;
    using System.Security.Claims;
    using System.Web;
    using WorkBasket.Data.Entities;
    using WorkBasket.Data.Repository;
    using WorkBasket.Infrastructure;

    public class LoginCallback : IHttpHandler
    {
        private readonly Auth0.Client client = new Auth0.Client(
                                ConfigurationManager.AppSettings["auth0:ClientId"],
                                ConfigurationManager.AppSettings["auth0:ClientSecret"],
                                ConfigurationManager.AppSettings["auth0:Domain"]);

        public void ProcessRequest(HttpContext context)
        {
            
        
            var token = client.ExchangeAuthorizationCodePerAccessToken(context.Request.QueryString["code"], context.Request.Url.ToString());
            var profile = client.GetUserInfo(token);

            var user = new List<KeyValuePair<string, object>>
            {
                new KeyValuePair<string, object>("name", profile.Name),
                new KeyValuePair<string, object>("email", profile.Email),
                new KeyValuePair<string, object>("family_name", profile.FamilyName),
                new KeyValuePair<string, object>("gender", profile.Gender),
                new KeyValuePair<string, object>("given_name", profile.GivenName),
                new KeyValuePair<string, object>("nickname", profile.Nickname),
                new KeyValuePair<string, object>("picture", profile.Picture),
                new KeyValuePair<string, object>("user_id", profile.UserId),
                new KeyValuePair<string, object>("id_token", token.IdToken),
                new KeyValuePair<string, object>("access_token", token.AccessToken),
                new KeyValuePair<string, object>("connection", profile.Identities.First().Connection),
                new KeyValuePair<string, object>("provider", profile.Identities.First().Provider)

            };



            // NOTE: Uncomment the following code in order to include claims from associated identities
            //profile.Identities.ToList().ForEach(i =>
            //{
            //    user.Add(new KeyValuePair<string, object>(i.Connection + ".access_token", i.AccessToken));
            //    user.Add(new KeyValuePair<string, object>(i.Connection + ".provider", i.Provider));
            //    user.Add(new KeyValuePair<string, object>(i.Connection + ".user_id", i.UserId));
            //});


            
            // NOTE: uncomment this if you send roles
            // user.Add(new KeyValuePair<string, object>(ClaimTypes.Role, profile.ExtraProperties["roles"]));

            // NOTE: this will set a cookie with all the user claims that will be converted 
            //       to a ClaimsPrincipal for each request using the SessionAuthenticationModule HttpModule. 
            //       You can choose your own mechanism to keep the user authenticated (FormsAuthentication, Session, etc.)
            FederatedAuthentication.SessionAuthenticationModule.CreateSessionCookie(user);
            
            if (context.Request.QueryString["state"] != null && context.Request.QueryString["state"].StartsWith("ru="))
            {
                var state = HttpUtility.ParseQueryString(context.Request.QueryString["state"]);
                context.Response.Redirect(state["ru"], true);
            }

            
            //Add user to database so you don't have to call Auth0 
            SOC soc = new SOC(new MyContext());

            string userid = ClaimsPrincipal.Current.FindFirst("user_id").Value;

            WBUser wbuser = soc.WBUsers.Where(c => c.user_id == userid).FirstOrDefault<WBUser>();

            bool IsNew= false;

            if (wbuser == null)
            {
                wbuser = new WBUser();
                
                IsNew = true;
            }
            wbuser.user_id = userid;
            wbuser.email = ClaimsPrincipal.Current.FindFirst("email").Value;
            wbuser.family_name = ClaimsPrincipal.Current.FindFirst("family_name").Value;
            wbuser.gender = ClaimsPrincipal.Current.FindFirst("gender").Value;
            wbuser.given_name = ClaimsPrincipal.Current.FindFirst("given_name").Value;
            wbuser.nickname = ClaimsPrincipal.Current.FindFirst("nickname").Value;
            wbuser.picture = ClaimsPrincipal.Current.FindFirst("picture").Value;
            wbuser.id_token = ClaimsPrincipal.Current.FindFirst("id_token").Value;
            wbuser.access_token = ClaimsPrincipal.Current.FindFirst("access_token").Value;
            wbuser.connection = ClaimsPrincipal.Current.FindFirst("connection").Value;
            wbuser.provider = ClaimsPrincipal.Current.FindFirst("provider").Value;
            wbuser.name = ClaimsPrincipal.Current.FindFirst("name").Value;

            if (IsNew)
            {
                soc.WBUsers.Add(wbuser);
            }
            else
            {
                soc.WBUsers.Update(wbuser);
            }
 
            soc.CommitChanges();

            context.Response.Redirect("/dash");
        }

        public bool IsReusable { get { return false; } }
    }
}